package com.briup.srms.sms.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.validation.constraints.NotNull;

import com.briup.srms.sms.bean.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import com.briup.srms.base.bean.BaseUser;
import com.briup.srms.base.bean.BaseUserExample;
import com.briup.srms.base.bean.extend.BaseUserExtend;
import com.briup.srms.base.dao.BaseUserMapper;
import com.briup.srms.base.service.IBaseUserService;
import com.briup.srms.sms.bean.extend.EmployeeEventExtend;
import com.briup.srms.sms.bean.extend.StudentEventExtend;
import com.briup.srms.sms.bean.extend.StudentExtend;
import com.briup.srms.sms.dao.ClazzMapper;
import com.briup.srms.sms.dao.DirectionMapper;
import com.briup.srms.sms.dao.EmployeeEventMapper;
import com.briup.srms.sms.dao.StudentEmploymentMapper;
import com.briup.srms.sms.dao.StudentEventMapper;
import com.briup.srms.sms.dao.StudentMapper;
import com.briup.srms.sms.dao.StudentTrainMapper;
import com.briup.srms.sms.dao.extend.ChannelExtendMapper;
import com.briup.srms.sms.dao.extend.ClazzExtendMapper;
import com.briup.srms.sms.dao.extend.StudentExtendMapper;
import com.briup.srms.sms.service.IStudentService;
import com.briup.srms.sms.vm.StudentClazzVM;
import com.briup.srms.sms.vm.StudentsDirectionVM;
import com.jacky.base.utils.CustomerException;
import com.jacky.base.utils.IDCardUtil;
import com.jacky.base.utils.PageVM;
import com.jacky.base.utils.RegExpValidation;

@Service
public class StudentServiceImpl implements IStudentService {

    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private StudentExtendMapper studentExtendMapper;
    @Autowired
    private DirectionMapper directionMapper;
    @Autowired
    private ClazzMapper clazzMapper;
    @Autowired
    private IBaseUserService baseUserService;
    @Autowired
    private StudentTrainMapper stMapper;
    @Autowired
    private BaseUserMapper baseUserMapper;
    @Autowired
    private StudentEmploymentMapper seMapper;
    @Autowired
    private EmployeeEventMapper employeeEventMapper;
    @Autowired
    private StudentEventMapper studentEventMapper;
    @Autowired
    private ClazzExtendMapper clazzExtendMapper;
    @Autowired
    private ChannelExtendMapper channelExtendMapper;

    @Override
    @Transactional
    public void batchInsertTrainStudent(List<Student> students, long trainId) throws CustomerException {
        for (Student s : students) {
            Student student = findStudentByStuNo(s.getStuNo());
            // 如果学生为空，录入学生信息
            if (student == null) {
                s.setStuType("实训");
                s.setStatus("实训中");
                s.setCreateTime(new Date().getTime());
                studentMapper.insert(s);
                student = s;
            }
            // 如果学生信息不为空，说明学生在，那么直接录入学生实训信息
            StudentTrain st = new StudentTrain();
            st.setStudentId(student.getId());
            st.setTrainId(trainId);
            stMapper.insert(st);
        }
    }

    @Override
    public Student findByIdCard(String idCard) {
        StudentExample example = new StudentExample();
        example.createCriteria().andIdCardEqualTo(idCard);
        List<Student> list = studentMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<Student> queryByClazzId(long clazzId) {
        StudentExample example = new StudentExample();
        example.createCriteria().andClazzIdEqualTo(clazzId);
        List<Student> list = studentMapper.selectByExample(example);
        return list;
    }


    @Override
    public Student findStudentByStuNo(String stuNo) {
        StudentExample example = new StudentExample();
        example.createCriteria().andStuNoEqualTo(stuNo);
        List<Student> list = studentMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public PageVM<StudentExtend> pageQuery(int page, int pageSize, String realname, Long trainId, Long channelId) {
        List<StudentExtend> list = studentExtendMapper.queryTrain(page, pageSize, realname, trainId, channelId);
        long total = studentExtendMapper.countTrain(realname, trainId, channelId);
        return new PageVM<>(page, pageSize, total, list);
    }

    @Override
    public PageVM<StudentExtend> pageQuery(int page, int pageSize, String realname,
                                           Long clazzId, String status, Long[] channelIds, String[] stuTypes, String year) {
        List<StudentExtend> list = studentExtendMapper.query(page, pageSize, realname, clazzId,
                status, channelIds, stuTypes, year);
        long total = studentExtendMapper.count(realname, clazzId, status, channelIds, stuTypes, year);
        return new PageVM<>(page, pageSize, total, list);
    }

    @Override
    @Transactional
    public void saveOrUpdate(Student student) {
        if (student.getId() == null) {
            // 检测身份证是否重复
            StudentExample example = new StudentExample();
            if (student.getIdCard() == null) {
                throw new CustomerException("身份证号不存在");
            }
            example.createCriteria().andIdCardEqualTo(student.getIdCard());
            List<Student> list = studentMapper.selectByExample(example);
            if (list.size() > 0) {
                throw new CustomerException("身份证号为 " + student.getIdCard() + " 的用户已经存在");
            }
            // 设置学生类型
            if (student.getStuType() == null) {
                student.setStuType("校招");
            }
            // 设置学生杰普学号
            if (student.getSchoolStuNo() != null) {
                student.setStuNo(student.getChannelId() + "_" + student.getSchoolStuNo());
            }
            // 状态报名中
            student.setStatus(StudentExtend.STATUS_APPLY);
            student.setApplyTime(new Date().getTime());
            studentMapper.insert(student);

            // 生成就业信息
            StudentEmployment employment = new StudentEmployment();
            employment.setIdCard(student.getIdCard());
            seMapper.insert(employment);

            student.setEmploymentId(employment.getId());
            studentMapper.updateByPrimaryKey(student);
        } else {
            // 查询学生是否存在
            Student student_db = studentMapper.selectByPrimaryKey(student.getId());
            if (!student_db.getClazzId().equals(student.getClazzId())) {
                Clazz clazz = clazzMapper.selectByPrimaryKey(student.getClazzId());
                student.setClazz(clazz.getName());
                if (clazz == null) {
                    throw new CustomerException("班级信息不存在");
                }
                // 修改方向
                Direction direction = directionMapper.selectByPrimaryKey(clazz.getDirectionId());
                if (direction == null) {
                    throw new CustomerException("方向信息不存在");
                }
                student.setDirectionId(direction.getId());
                student.setDirection(direction.getName());
            }

            studentMapper.updateByPrimaryKey(student);
        }

    }

    @Override
    @Transactional
    public void batchDelete(Long[] ids) {
        for (long id : ids) {
            this.deleteById(id);
        }
    }

    @Override
    public void deleteById(long id) {
        Student dict = studentMapper.selectByPrimaryKey(id);
        if (dict == null) {
            throw new CustomerException("要删除的数据不存在");
        }
        studentMapper.deleteByPrimaryKey(id);
    }

    @Override
    @Transactional
    public void batchInsert(List<Student> students) throws CustomerException {
        for (Student student : students) {
            student.setStatus(StudentExtend.STATUS_APPLY);
            this.saveOrUpdate(student);
        }
    }

    @Override
    @Transactional
    public void batchConfirmDirection(StudentsDirectionVM sdvm) throws CustomerException {
        // 查询出方向信息
        Direction direction = directionMapper.selectByPrimaryKey(sdvm.getDirectionId());
        // 批量更改方向
        for (long id : sdvm.getIds()) {
            Student student = studentMapper.selectByPrimaryKey(id);
            if (student != null) {
                if (!student.getStatus().equals(StudentExtend.STATUS_APPLY_CONFIRM)) {
                    throw new CustomerException("学生状态为待选方向时才可以确认方向");
                }
                // 方向已确认
                student.setStatus(StudentExtend.STATUS_DIRECTION_CONFIRM);
                student.setDirectionId(sdvm.getDirectionId());
                student.setDirection(direction.getName());
                student.setDirectionTime(new Date().getTime());
                studentMapper.updateByPrimaryKey(student);
            }
        }
    }

    @Override
    @Transactional
    public void batchConfirmClazz(StudentClazzVM scvm) {
        // 查询出班级信息
        Clazz clazz = clazzMapper.selectByPrimaryKey(scvm.getClazzId());
        // 批量更改班级
        for (long id : scvm.getIds()) {
            Student student = studentMapper.selectByPrimaryKey(id);
            if (student != null) {
                // 班级已确认
                student.setStatus(StudentExtend.STATUS_CLAZZ_CONFIRM);
                student.setClazzId(scvm.getClazzId());
                student.setClazz(clazz.getName());
                studentMapper.updateByPrimaryKey(student);
            }
        }
    }

    @Override
    public Student findByAccountId(@NotNull long id) {
        StudentExample example = new StudentExample();
        example.createCriteria().andUserIdEqualTo(id);
        List<Student> list = studentMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    @Transactional
    public void batchUpdateTuition(Long[] ids, String tuition, String reserve) {
        // TODO Auto-generated method stub
        // 遍历,批量插入用户信息
        for (long id : ids) {
            Student student = studentMapper.selectByPrimaryKey(id);
            if (student != null) {
                // 维护费用信息
                student.setTuition(tuition);
                if (StringUtils.isEmpty(reserve)) {
                    reserve = "0";
                }
                student.setReserve(reserve);
                studentMapper.updateByPrimaryKey(student);
            }
        }
    }

    @Override
    @Transactional
    public void batchConfirmApplay(Long[] ids, String tuition, String reserve) {
        // 遍历,批量插入用户信息
        for (long id : ids) {
            Student student = studentMapper.selectByPrimaryKey(id);
            if (student != null) {
                this.confirmApply(student, tuition, reserve);
            }
        }
    }

    private void confirmApply(Student student, String tuition, String reserve) {
        this.generatorAccount(student);
        // 维护费用信息
        student.setTuition(tuition);
        if (StringUtils.isEmpty(reserve)) {
            reserve = "0";
        }
        student.setReserve(reserve);
        studentMapper.updateByPrimaryKey(student);
    }

    @Override
    public void attention(@NotNull long id, String type, String comment) {
        Student student = studentMapper.selectByPrimaryKey(id);
        if (student == null) {
            throw new CustomerException("学生信息不存在");
        }
        student.setIsAttention(type);
        student.setComment(comment);
        studentMapper.updateByPrimaryKey(student);
    }

    @Override
    public void cancelAttention(@NotNull long id) {
        this.attention(id, null, null);
    }

    @Override
    public void report(@NotNull long id, String dormitoryType, String dormitory) {
        Student student = studentMapper.selectByPrimaryKey(id);
        if (student == null) {
            throw new CustomerException("学生信息不存在");
        }
        student.setDormitoryType(dormitoryType);
        student.setDormitory(dormitory);
        student.setLocation("基地");
        student.setReportTime(new Date().getTime());
        studentMapper.updateByPrimaryKey(student);
    }

    @Override
    public void talk(long employeeId, long studentId, String content) {
        // 插入教师事件
        EmployeeEvent ee = new EmployeeEvent();
        ee.setEmployeeId(employeeId);
        ee.setStudentId(studentId);
        ee.setContent(content);
        ee.setEvent(EmployeeEventExtend.EVENT_TALK);
        ee.setInsertTime(new Date().getTime());
        employeeEventMapper.insert(ee);

        //更新谈话记录
        Student student = studentMapper.selectByPrimaryKey(studentId);
        String discussion = student.getDiscussion();
        if (discussion == null) {
            discussion = "";
        }
        student.setDiscussion(content.concat(discussion));
        studentMapper.updateByPrimaryKey(student);
    }

    @Override
    @Transactional
    public void generatorAccount(Long[] ids) throws CustomerException {
        for (long id : ids) {
            Student student = studentMapper.selectByPrimaryKey(id);
            if (student != null) {
                this.generatorAccount(student);
            }
        }
    }

    private void generatorAccount(Student student) {
        BaseUserExample example = new BaseUserExample();
        example.createCriteria().andUsernameEqualTo(student.getIdCard());
        List<BaseUser> list = baseUserMapper.selectByExample(example);
        if (list.size() > 0) {
            throw new CustomerException("账号为" + list.get(0).getUsername() + "的用户已经被占用");
        }
        // 1. 生成账号信息
        BaseUser user = new BaseUser();
        user.setAvatar("http://121.199.29.84:8888/group1/M00/00/12/rBD-SV-Td6-Aawn0AACq962TS9c719.jpg");
        user.setRegisterTime(new Date().getTime());
        // 身份证号作为用户名
        user.setUsername(student.getIdCard());
        user.setPassword("123456");
        // 保存用户信息
        baseUserService.addUserWidthRole(user, 6l);
        // 2.1 维护用户与学生信息之间的关系
        student.setUserId(user.getId());
        studentMapper.updateByPrimaryKey(student);
    }

    @Override
    @Transactional
    public void changeClazz(Long[] studentIds, Long clazzId, String comment) {
        if (studentIds == null) {
            throw new CustomerException("请选中学生信息");
        }
        Clazz clazz = clazzMapper.selectByPrimaryKey(clazzId);
        if (clazz == null) {
            throw new CustomerException("班级信息不存在");
        }
        for (long studentId : studentIds) {
            // 查询学生是否存在
            Student student = studentMapper.selectByPrimaryKey(studentId);
            String oldClazz = student.getClazz();
            // 修改班级
            student.setClazzId(clazzId);
            student.setClazz(clazz.getName());
            // 修改方向
            Direction direction = directionMapper.selectByPrimaryKey(clazz.getDirectionId());
            if (direction != null) {
                student.setDirectionId(direction.getId());
                student.setDirection(direction.getName());
            }
            // 更新
            studentMapper.updateByPrimaryKey(student);
            // 添加日志
            StudentEvent se = new StudentEvent();
            se.setContent("从" + oldClazz + "转到了" + student.getClazz() + "," + comment);
            se.setEvent(StudentEventExtend.EVENT_CHANGE_CLAZZ);
            se.setInsertTime(new Date().getTime());
            se.setStudentId(studentId);
            studentEventMapper.insert(se);
        }
        // 修改班级总人数
        clazz.setTotal(clazz.getTotal() + studentIds.length);
        clazzMapper.updateByPrimaryKey(clazz);
    }


    @Override
    @Transactional
    public void batchInsertOldStudent(List<Student> students) throws CustomerException {
        for (Student student : students) {
            String clazzName = student.getClazz();
            String school = student.getSchool();
            String college = student.getCollege();
            if (StringUtils.isEmpty(clazzName) || StringUtils.isEmpty(school) || StringUtils.isEmpty(college)) {
                throw new CustomerException("档案信息不全");
            }
            // 数据校验 获取班级、渠道、方向、、、
            Clazz clazz = clazzExtendMapper.queryByName(clazzName);
            if (clazz == null) {
                throw new CustomerException("班级信息不存在：" + student.getClazz());
            }
            Channel channel = channelExtendMapper.queryBySchoolCollegeName(school, college);
            if (channel == null) {
                throw new CustomerException("渠道信息不存在：学校-" + school + "，学院-" + college);
            }
            if (clazz.getDirectionId() == null) {
                throw new CustomerException("方向不存在：" + clazzName);
            }
            Direction direction = directionMapper.selectByPrimaryKey(clazz.getDirectionId());
            if (direction == null) {
                throw new CustomerException("方向不存在：" + clazz.getDirectionId());
            }
            // 3. 确认学生学习方向
            student.setDirection(direction.getName());
            student.setDirectionId(direction.getId());
            // 4. 为学生分班
            student.setClazz(clazz.getName());
            student.setClazzId(clazz.getId());
            // 5. 学生渠道
            student.setChannelId(channel.getId());

            // 1. 插入学生档案
            this.saveOrUpdate(student);
            // 2. 确认学生信息（产生学生账号）
            this.confirmApply(student, "0", "0");
            // 3. 更新学生状态
            student.setStatus(StudentExtend.STATUS_CLAZZ_CONFIRM);
            studentMapper.updateByPrimaryKey(student);
        }
    }

    @Override
    @Transactional
    public void batchInsertClazzStudent(List<Student> students) throws CustomerException {
        for (Student student : students) {
            String school = student.getSchool();
            String college = student.getCollege();
            Clazz clazz = clazzMapper.selectByPrimaryKey(student.getClazzId());
            if (clazz == null) {
                throw new CustomerException("班级不存在");
            }
            // 数据校验 获取班级、渠道、方向、、、
            if (clazz == null) {
                throw new CustomerException("班级信息不存在：" + student.getClazz());
            }
            Channel channel = channelExtendMapper.queryBySchoolCollegeName(school, college);
            if (channel == null) {
                throw new CustomerException("渠道信息不存在：学校-" + school + "，学院-" + college);
            }
            if (clazz.getDirectionId() == null) {
                throw new CustomerException("方向不存在：" + clazz.getName());
            }
            Direction direction = directionMapper.selectByPrimaryKey(clazz.getDirectionId());
            if (direction == null) {
                throw new CustomerException("方向不存在：" + clazz.getDirectionId());
            }
            // 3. 确认学生学习方向
            student.setDirection(direction.getName());
            student.setDirectionId(direction.getId());
            // 4. 为学生分班
            student.setClazz(clazz.getName());
            student.setClazzId(clazz.getId());
            // 5. 学生渠道
            student.setChannelId(channel.getId());

            // 1. 插入学生档案
            this.saveOrUpdate(student);
            // 2. 确认学生信息（产生学生账号）
            this.confirmApply(student, "0", "0");
            // 3. 更新学生状态
            student.setStatus(StudentExtend.STATUS_CLAZZ_CONFIRM);
            studentMapper.updateByPrimaryKey(student);
        }
    }

    @Override
    @Transactional
    public void leaveBriup(Long studentId) {
        // 1. 更改学生状态
        Student student = studentMapper.selectByPrimaryKey(studentId);
        if (student == null) {
            throw new CustomerException("学生信息不存在");
        }
        student.setStatus(StudentExtend.STATUS_LEAVE);
        studentMapper.updateByPrimaryKey(student);
        // 2. 禁用学生账号
        BaseUser user = baseUserMapper.selectByPrimaryKey(student.getUserId());
        if (user != null) {
            user.setStatus(BaseUserExtend.STATUS_FORBIDDEN);
            baseUserMapper.updateByPrimaryKey(user);
        }

        // 3. 更改班级离校人数
        Clazz clazz = clazzMapper.selectByPrimaryKey(student.getClazzId());
        if (clazz != null) {
            clazz.setLeaveNum(clazz.getLeaveNum() + 1);
            clazzMapper.updateByPrimaryKey(clazz);
        }
    }

    @Transactional
    @Override
    public void backBriup(Long stuId, Long clazzId) {
        // 判断学生是否存在
        Student student = studentMapper.selectByPrimaryKey(stuId);
        if (student == null) {
            throw new CustomerException("学生信息不存在");
        }
        // 修改状态位为"学习中"，修改学生班级
        // 修改班级和方向
        student.setStatus(StudentExtend.STATUS_CLAZZ_CONFIRM);
        studentMapper.updateByPrimaryKey(student);

        // 解除学生账号禁用状态
        BaseUser user = baseUserMapper.selectByPrimaryKey(stuId);
        if (user != null) {
            user.setStatus(BaseUserExtend.STATUS_NORMAL);
            baseUserMapper.updateByPrimaryKey(user);
        }
        // 更改班级离校人数
        Clazz clazz = clazzMapper.selectByPrimaryKey(student.getClazzId());
        if (clazz != null) {
            clazz.setLeaveNum(clazz.getLeaveNum() - 1);
            clazzMapper.updateByPrimaryKey(clazz);
        }
    }

    @Override
    @Transactional
    public void register(Student student) {
        // 1. ---------身份证号
        String idCard = student.getIdCard();
        if (!RegExpValidation.checkIdCard(idCard)) {
            throw new CustomerException("身份证号错误【" + idCard + "】");
        }
        // 设置身份证号
        String birth = IDCardUtil.getBirAgeSex(idCard).get("birthday");
        // 设置出生日期
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = simpleDateFormat.parse(birth);
            long ts = date.getTime();
            student.setBirth(ts);
        } catch (Exception e) {
            // 生日为当前时间
            student.setBirth(new Date().getTime());
        }
        //2. ---------手机号
        if (!RegExpValidation.checkMobile(student.getTel())) {
            throw new CustomerException("手机号格式错误【" + student.getTel() + "】");
        }
        //3. ---------监护人手机号
        if (!RegExpValidation.checkMobile(student.getGuardianTel())) {
            throw new CustomerException("监护人手机号格式错误【" + student.getGuardianTel() + "】");
        }
        //4. ---------钉钉手机号
        if (!RegExpValidation.checkMobile(student.getDdTel())) {
            throw new CustomerException("手机号格式错误【" + student.getDdTel() + "】");
        }

        // 设置班级和方向信息
        Clazz clazz = clazzMapper.selectByPrimaryKey(student.getClazzId());
        if (clazz != null) {
            student.setClazz(clazz.getName());
        }
        Direction direction = directionMapper.selectByPrimaryKey(student.getDirectionId());
        if (direction != null) {
            student.setDirection(direction.getName());
            student.setDirectionTime(new Date().getTime());
        }
        // 保存学生信息，确认学生报名信息，生成账号信息
        this.saveOrUpdate(student);
        this.confirmApply(student, "0", "0");
        // 更新学生状态
        student.setStatus(StudentExtend.STATUS_CLAZZ_CONFIRM);
        studentMapper.updateByPrimaryKey(student);
    }

    @Override
    public void resetPassword(long id) {
        Student student = studentMapper.selectByPrimaryKey(id);
        if (student == null) {
            throw new CustomerException("学生信息不存在");
        }
        BaseUser user = baseUserMapper.selectByPrimaryKey(student.getUserId());
        if (user == null) {
            throw new CustomerException("账户信息不存在");
        }
        String md5Password = DigestUtils.md5DigestAsHex("123456".getBytes());
        user.setPassword(md5Password);
        baseUserMapper.updateByPrimaryKey(user);
    }

    @Override
    @Transactional
    public void test_generator_employment() {
        List<Student> students = studentMapper.selectByExample(new StudentExample());
        for (Student s : students) {
            // 维护学生就业信息
            StudentEmployment se = new StudentEmployment();
            se.setIdCard(s.getIdCard());
            seMapper.insert(se);

            s.setEmploymentId(se.getId());
            studentMapper.updateByPrimaryKey(s);

        }
    }


}
